package org.zxt.web.nacos;

import com.alibaba.fastjson.parser.Feature;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import java.util.concurrent.*;
import java.util.function.Consumer;

public class NacosDiscoveryClient {
    private String host;
    private Map<String, String> props;
    private static final String INSTANCE_API = "/nacos/v1/ns/instance";
    private static final String BEAT_API = "/nacos/v1/ns/instance/beat";
    private String api;
    public NacosDiscoveryClient(String host, Map<String, String> props) {
        this.host = host;
        this.props = props;
        this.api = "http://"+host+INSTANCE_API;
    }

    private static final String META_FORM = "application/x-www-form-urlencoded";
    ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
    public void register() {
//        sendPost(api, "port="+props.get("port")+"&healthy=true&ip="+props.get("ip")+"&weight=1.0&serviceName="+props.get("serviceName")+"&encoding=GBK&namespaceId="+props.get("namespaceId"));
        sendPing();
    }

    private void sendPing(){
        Runnable run = ()->{
            if(!props.containsKey("beat")) {
                try {
                    String json = "{\"ip\":\"" + props.get("ip") + "\",\"metadata\":{\"preserved.register.source\":\"simple-web\"},\"port\":" + props.get("port") + ",\"scheduled\":true,\"serviceName\":\"" + props.get("serviceName") + "\",\"weight\":1}";
                    props.put("beat", URLEncoder.encode(json, "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }
            sendPut("http://"+host+BEAT_API, "serviceName="+props.get("serviceName")+"&ip="+props.get("ip")+"&namespaceId="+props.get("namespaceId")+"&port="+props.get("port")+"&beat="+props.get("beat"));
        };
        service.scheduleWithFixedDelay(run, 5,9, TimeUnit.SECONDS);
    }

    private static void sendGet(String path){
        sendHttp("GET", META_FORM, path, null, (v)->{});
    }
    private static void sendPost(String path, String body){
        sendHttp("POST", META_FORM, path, body, (v)->{});
    }
    private static void sendPut(String path, String body){
        sendHttp("PUT", META_FORM, path, body, (v)->{});
    }

    private static void sendDelete(String path, String body){
        sendHttp("DELETE", META_FORM, path, body, (v)->{});
    }
    private static void sendHttp(String method, String contentType, String path, String body, Consumer<HttpURLConnection> consumer){
        HttpURLConnection conn = null;
        try {
            URL url = new URL(path); // 替换为你的URL
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod(method);
            conn.setDoOutput(true);

            // 设置请求头，如Content-Type
            conn.setRequestProperty("Content-Type", contentType);

            if(body != null){
                // 发送请求参数
                try (OutputStream os = conn.getOutputStream()) {
                    os.write(body.getBytes());
                }
            }
            // 获取响应码
            int responseCode = conn.getResponseCode();
            if(responseCode != 200){
                System.out.println("nacos regist error");
            }
            InputStream ins = conn.getInputStream();
            byte[] bs = new byte[1024];
            int len = 0;
            while ((len = ins.read(bs)) != -1){
                System.out.print(new String(bs, 0, len));
            }
            System.out.println();
            consumer.accept(conn);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(conn != null){
                conn.disconnect();
            }
        }
    }

    public void stop() {
        System.out.println("nacos client stop");
        sendDelete(api+"?serviceName="+props.get("serviceName")+"&ip="+props.get("ip")+"&port="+props.get("port")+"&namespaceId="+props.get("namespaceId"), null);
        service.shutdown();
    }
}
